package cn.walls1717.juc.tl;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 内存泄漏测试
 *
 * @author walls1717
 * @create 2022/12/14 14:33
 **/
@Slf4j
public class ThreadLocal2Demo {

    public static void main(String[] args) throws InterruptedException {
        MyData myData = new MyData();
        ExecutorService executor = Executors.newFixedThreadPool(3);

        for (int i = 0; i <= 10 ; i++) {
            executor.submit(()->{
                try {
                    Integer start = myData.num.get();
                    myData.add();
                    Integer after = myData.num.get();
                    log.info("start" + start +  " | after" + after);
                } finally {
                    /*
                    因为使用的是线程池，线程池里面总共就只有3个线程，这三个线程是复用的，如果不对
                    ThreadLocal进行remove的话，下一个方法重新获得此线程，再次操作ThreadLocal，
                    数据会累加，会使ThreadLocal越来越大，造成内存溢出。
                     */
                    myData.num.remove();
                }
            });
        }

        executor.shutdown();
    }
}

class MyData {
    ThreadLocal<Integer> num = ThreadLocal.withInitial(()->0);

    public void add() {
        num.set(num.get() + 1);
    }
}